<?php

namespace App\Traits;

use Illuminate\Support\Str;

trait HasSlug
{
    /**
     * Boot the trait
     */
    protected static function bootHasSlug()
    {
        static::creating(function ($model) {
            if (empty($model->slug)) {
                $model->slug = $model->generateSlug();
            }
        });

        static::updating(function ($model) {
            if ($model->isDirty($model->getSlugSourceField()) && empty($model->slug)) {
                $model->slug = $model->generateSlug();
            }
        });
    }

    /**
     * 获取用于生成slug的字段
     */
    protected function getSlugSourceField(): string
    {
        return $this->slugSourceField ?? 'name';
    }

    /**
     * 生成slug
     */
    public function generateSlug(): string
    {
        $sourceField = $this->getSlugSourceField();
        $sourceValue = $this->getAttribute($sourceField);
        
        if (empty($sourceValue)) {
            return '';
        }

        $slug = Str::slug($sourceValue);
        $originalSlug = $slug;
        $counter = 1;

        // 确保slug唯一性
        while ($this->slugExists($slug)) {
            $slug = $originalSlug . '-' . $counter;
            $counter++;
        }

        return $slug;
    }

    /**
     * 检查slug是否存在
     */
    protected function slugExists(string $slug): bool
    {
        $query = static::where('slug', $slug);
        
        // 如果是更新操作，排除当前记录
        if ($this->exists) {
            $query->where($this->getKeyName(), '!=', $this->getKey());
        }

        return $query->exists();
    }

    /**
     * 根据slug查找记录
     */
    public function scopeBySlug($query, string $slug)
    {
        return $query->where('slug', $slug);
    }

    /**
     * 根据slug查找记录或失败
     */
    public function scopeBySlugOrFail($query, string $slug)
    {
        return $query->where('slug', $slug)->firstOrFail();
    }

    /**
     * 更新slug
     */
    public function updateSlug(): bool
    {
        $newSlug = $this->generateSlug();
        
        if ($newSlug !== $this->slug) {
            return $this->update(['slug' => $newSlug]);
        }

        return true;
    }

    /**
     * 获取slug URL
     */
    public function getSlugUrlAttribute(): string
    {
        return route($this->getSlugRouteName(), $this->slug);
    }

    /**
     * 获取slug路由名称
     */
    protected function getSlugRouteName(): string
    {
        return $this->slugRouteName ?? strtolower(class_basename($this)) . '.show';
    }

    /**
     * 设置slug路由名称
     */
    public function setSlugRouteName(string $routeName): void
    {
        $this->slugRouteName = $routeName;
    }

    /**
     * 检查slug是否有效
     */
    public function hasValidSlug(): bool
    {
        return !empty($this->slug) && $this->slug === Str::slug($this->slug);
    }

    /**
     * 重新生成slug
     */
    public function regenerateSlug(): bool
    {
        $this->slug = null;
        return $this->updateSlug();
    }

    /**
     * 获取slug显示文本
     */
    public function getSlugDisplayAttribute(): string
    {
        return $this->slug ?: '未设置';
    }

    /**
     * 检查slug是否与源字段同步
     */
    public function isSlugSynced(): bool
    {
        $sourceField = $this->getSlugSourceField();
        $expectedSlug = Str::slug($this->getAttribute($sourceField));
        
        return $this->slug === $expectedSlug;
    }

    /**
     * 同步slug
     */
    public function syncSlug(): bool
    {
        if (!$this->isSlugSynced()) {
            return $this->regenerateSlug();
        }

        return true;
    }
}
